<template>
	<div @scroll="handleScroll" :class="`px-5 h-100 hideScrollBar ${isRequesting ? 'overflow-hidden' : 'overflow-scroll'}`">
		<div class="topArea mt-3 d-flex position-relative">
			<CustomImg class="rounded-5 overflow-hidden" width="200" height="200" :src="artist.img1v1Url" />
			<div class="ms-5">
				<div class="fs-3 fw-bold">{{ artist.name }}</div>
				<div class="alias text-muted">{{ artist.alias?.join("、") }}</div>

				<template v-if="!isSubed">
					<div @click="subArtist(1)" class="collect my-3 rounded-pill border flex-center cursor-pointer hover-btn">
						<CollectListIcon class="flex-shrink-0" width="20" height="20" />
						<span class="ms-2 flex-shrink-0">收藏</span>
					</div>
				</template>
				<template v-else>
					<div @click="subArtist(0)" class="collect my-3 rounded-pill border flex-center cursor-pointer hover-btn">
						<CollectListIcon color="rgba(0,0,0,.5)" class="flex-shrink-0" width="20" height="20" />
						<span class="ms-2 flex-shrink-0 text-dark-50">已收藏</span>
					</div>
				</template>

				<div class="canSelect">
					<span
						>单曲数:<span class="text-muted">{{ artist.musicSize }}</span></span
					>
					<span class="d-inline-block mx-4"
						>专辑数:<span class="text-muted">{{ artist.albumSize }}</span></span
					>
					<span
						>MV数:<span class="text-muted">{{ artist.mvSize }}</span></span
					>
				</div>
			</div>
		</div>
		<HorizontalNav class="mt-4" v-model:navs="navs" />
		<div class="boderLine w-100 border-top ms-2 mb-4"></div>
		<template v-if="currentActiveNavIndex === 0">
			<div class="d-flex">
				<div class="top50Cover rounded-4 overflow-hidden position-relative text-white flex-center flex-column fw-bold me-3">
					<div>TOP</div>
					<div>50</div>
				</div>
				<div class="ms-5 flex-grow-1">
					<div class="d-flex align-items-center mb-3">
						<span class="fs-5 fw-bold me-4">热门50首</span>
						<playSolidInnerIcon
							@click="
								playingSongs = realSongs;
								playAll.clickPlayAll();
							"
							class="ms-1 hover-opacity"
							width="18"
							height="18"
						/>
						<Divider class="mx-4" />
						<AddToCollectionIcon
							@click="
								collectingSongs = realSongs;
								colVisible = true;
							"
							class="hover-opacity"
							width="18"
							height="18"
						/>
					</div>
					<MusicList
						:columns="columns"
						:dataSource="songs.map((item, index) => ({ ...item, index: index }))"
						:startSpace="false"
						:colItemStyle="{ padding: '.7rem' }"
					>
						<template #toolBar="{ id: musicId, index, name }">
							<span class="text-muted me-3">{{ String(index + 1).padStart(2, "0") }}</span>
							<span class="me-3">
								<LikedIcon
									class="cursor-pointer"
									v-if="!likedMusicList.includes(musicId)"
									@click="collectMusic(true, musicId)"
									width="15"
									height="15"
								/>
								<HaveLikedIcon class="cursor-pointer" v-else @click="collectMusic(false, musicId)" width="15" height="15" />
							</span>
							<DownloadMusicIcon @click="handleDownloadMusic({ id: musicId, name })" class="cursor-pointer" width="15" height="15" />
						</template>
					</MusicList>
					<div
						v-if="songs.length === 10"
						@click="songs = realSongs"
						style="background: #f1f1f1; margin-left: calc(1.5rem / -2)"
						class="py-2 findAll text-end cursor-pointer w-100 text-muted"
					>
						查看全部{{ realSongs.length }}首 >
					</div>
				</div>
			</div>

			<div class="albums">
				<div class="d-flex mb-5" v-for="(album, albumIndex) in hotAlbums" :key="albumIndex">
					<div class="me-3">
						<AlbumCover size="150" @click="navigateToAlbumDetail(album.id)" :src="album.picUrl" />
						<div class="fs-5 text-muted">
							{{ YYYYMMDD(album.publishTime) }}
						</div>
					</div>

					<div class="flex-grow-1 ms-5">
						<div class="d-flex align-items-center mb-3">
							<span
								@click="navigateToAlbumDetail(album.id)"
								class="fs-5 fw-bold me-4 albumName text-ellipsis cursor-pointer"
								:title="album.name"
								>{{ album.name }}</span
							>
							<playSolidInnerIcon
								@click="
									playingSongs = album.realSongs;
									playAll.clickPlayAll();
								"
								class="ms-1 hover-opacity"
								width="18"
								height="18"
							/>
							<Divider class="mx-4" />
							<AddToCollectionIcon
								@click="
									collectingSongs = album.realSongs;
									colVisible = true;
								"
								class="hover-opacity"
								width="18"
								height="18"
							/>
						</div>
						<MusicList
							:columns="columns"
							:dataSource="album.songs.map((item, index) => ({ ...item, index: index }))"
							:startSpace="false"
							:colItemStyle="{ padding: '.7rem' }"
						>
							<template #toolBar="{ id: musicId, index, name }">
								<span class="text-muted me-3">{{ String(index + 1).padStart(2, "0") }}</span>
								<span class="me-3">
									<LikedIcon
										class="cursor-pointer"
										v-if="!likedMusicList.includes(musicId)"
										@click="collectMusic(true, musicId)"
										width="15"
										height="15"
									/>
									<HaveLikedIcon class="cursor-pointer" v-else @click="collectMusic(false, musicId)" width="15" height="15" />
								</span>
								<DownloadMusicIcon
									@click="handleDownloadMusic({ id: musicId, name })"
									class="cursor-pointer"
									width="15"
									height="15"
								/>
							</template>
						</MusicList>
						<div
							v-if="album?.realSongs?.length > album?.songs?.length"
							style="background: #f1f1f1; margin-left: calc(1.5rem / -2)"
							class="py-2 findAll text-end cursor-pointer w-100 text-muted"
							@click="navigateToAlbumDetail(album.id)"
						>
							查看全部 >
						</div>
					</div>
				</div>
			</div>
		</template>
		<template v-if="currentActiveNavIndex === 2">
			<div class="canSelect">
				<div class="fw-bold fs-5 mb-4">
					<span>{{ artist.name }}</span>
					<span>简介</span>
				</div>
				<div class="text-muted mb-4 textDes">
					{{ artistDesc.briefDesc }}
				</div>

				<template v-for="(item, index) in artistDesc.introduction" :key="index">
					<div class="fw-bold fs-5 mb-4">{{ item.ti }}</div>
					<div class="text-muted mb-4 textDes">
						<p v-for="(txtItem, txtIndex) in item.txt.split('\n')" :key="txtIndex">{{ txtItem }}</p>
					</div>
				</template>
			</div>
		</template>
		<template v-if="currentActiveNavIndex === 3">
			<div class="d-flex flex-wrap justify-content-between">
				<ArtistItem
					class="mb-5"
					v-for="(artist, artistIndex) in similarArtists"
					:key="artistIndex"
					columns="5"
					:picUrl="artist.picUrl"
					:name="artist.name"
					:id="artist.id"
					:toDetail="true"
				/>
			</div>
		</template>
	</div>
	<PlayAllListBtn :visible="false" :musicList="playingSongs" ref="playAll" />
	<CollectionListModal :tracks="collectingSongs.map((item) => item.id).reverse()" v-model:visible="colVisible" />
</template>

<script lang="ts">
import {
	getArtistsApi,
	getSubListApi,
	getTop50Api,
	subArtistApi,
	getArtistListApi,
	getArtistAlbumApi,
	getArtistDetailApi,
	getArtistDescApi,
	getSimilarArtistApi,
} from "@/api/artist";
import { getAlbumApi } from "@/api/album";
import { likeMusic } from "@/api/discover";
import { getSongUrlApi } from "@/api/song";
import { throttle } from "@/utils";
import { scrollToBottom } from "@/utils/document";
import { downloadMusic } from "@/utils/file";
import { addHaveUrl, playTime, YYYYMMDD } from "@/utils/filters";
import { AxiosResponseProps } from "@/utils/request";
import { computed, defineComponent, getCurrentInstance, onMounted, reactive, ref, toRefs, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
interface Albums extends AxiosResponseProps {
	hotAlbums: any[];
	more: boolean;
}
export interface AlbumDetail extends AxiosResponseProps {
	songs: any[];
	album: {
		info: any;
	};
}
interface SimilarArtistsResponse extends AxiosResponseProps {
	artists: any[];
}
interface Top50Response extends AxiosResponseProps {
	songs: any[];
}
export default defineComponent({
	setup() {
		const route = useRoute();
		const router = useRouter();
		const store = useStore();
		const id = computed(() => route.query.id as string);
		const state = reactive({
			artist: {},
			navs: [
				{
					title: "专辑",
					active: true,
				},
				{
					title: "MV",
				},
				{
					title: "歌手详情",
				},
				{
					title: "相似歌手",
				},
			],
			realSongs: [],
			songs: [],
			subList: [],
			columns: [
				{
					span: 2,
					dataIndex: "toolBar",
					slots: { customRender: "toolBar" },
					colItemStyle: { "text-align": "center" },
				},
				{
					span: 9,
					dataIndex: "name",
				},
				{
					span: 1,
					dataIndex: "dt",
					render: (text) => {
						return playTime(text);
					},
				},
			],
			likedMusicList: computed(() => store.state.likedMusicList),
			playAll: ref(null),
			hotAlbums: [],
			playingSongs: [],
			isRequesting: false,
			artistCoverLoaded: false,
			colVisible: false,
			collectingSongs: [],
			artistDesc: null,
			similarArtists: [],
		});
		onMounted(() => {
			watch(
				() => route.query,
				() => {
					getArtistAlbum();
					getArtistDesc();
					getSimilarArtist();
					getArtist();
					getTop50();
					getSubList();
				},
				{
					immediate: true,
				}
			);
		});
		const currentActiveNavIndex = computed(() => state.navs.map((item, index) => ({ ...item, index })).find((item) => item.active)?.index || 0);
		const isSubed = computed(() => state.subList.some((item) => item.id === id.value));
		const {
			appContext: {
				config: {
					globalProperties: { $toast },
				},
			},
		} = getCurrentInstance();

		const getArtist = () => {
			getArtistsApi(id.value).then((res: any) => {
				if (res.code === 200) {
					state.artist = res.artist;
				}
			});
		};

		const getTop50 = () => {
			getTop50Api(id.value).then((res: Partial<Top50Response>) => {
				if (res.code === 200) {
					state.songs = res.songs.slice(0, 10);
					state.realSongs = res.songs;
				}
			});
		};

		const getSubList = () => {
			return getSubListApi().then((res: any) => {
				if (res.code === 200) {
					state.subList = res.data;
				}
			});
		};

		const subArtist = (t) => {
			subArtistApi({ id: id.value, t })
				.then(async (res: AxiosResponseProps) => {
					if (res.code === 200) {
						await getSubList();
						if (t) {
							$toast.success("收藏成功");
						} else {
							$toast.success("已取消收藏");
						}
					}
				})
				.catch((err) => {
					if (err.code === -462) {
						console.warn(err?.data.blockText);
						$toast.error(err?.data.blockText);
					}
				});
		};
		const collectMusic = (like, id) => {
			likeMusic({ id: id.value, like }).then(async (res: any) => {
				if (res.code === 200) {
					await store.dispatch("getLikedMusicList");
					$toast.success(like ? "已添加到我喜欢的音乐" : "取消喜欢成功");
				}
			});
		};
		const handleDownloadMusic = ({ id, name }) => {
			getSongUrlApi({ id: id.value }).then((res: AxiosResponseProps) => {
				if (res.code === 200) {
					let urls = res.data;
					if (urls && urls.length) {
						downloadMusic(urls[0].url, name)
							.then(() => {
								$toast.success("已添加至下载");
							})
							.catch(() => {
								$toast.warn("下载失败");
							});
					} else {
						$toast.warn("获取音乐链接失败");
					}
				}
			});
		};

		const getArtistAlbum = () => {
			getArtistAlbumApi({ id: id.value }).then((res: Partial<Albums>) => {
				if (res.code === 200) {
					state.hotAlbums = res.hotAlbums;
					state.hotAlbums.forEach((item, index) => {
						getAlbumApi(item.id).then(async (res: Partial<AlbumDetail>) => {
							if (res.code === 200) {
								res.songs = await addHaveUrl(res.songs);
								state.hotAlbums[index].songs = res.songs.slice(0, 10);
								state.hotAlbums[index].realSongs = res.songs;
							}
						});
					});
				}
			});
		};

		let offset = 0;
		let moreAlbum = true;
		const concatAlbums = () => {
			if (!moreAlbum) return $toast.success("没有更多了~");
			if (state.isRequesting) return;
			offset += 10;
			getArtistAlbumApi({ id: id.value, offset })
				.then((res: Partial<Albums>) => {
					if (res.code === 200) {
						moreAlbum = res.more;
						if (!res?.hotAlbums.length) {
							moreAlbum = false;
							return $toast.success("没有更多了~");
						}
						state.hotAlbums = [...state.hotAlbums, ...res.hotAlbums];
						state.hotAlbums.forEach((item, index) => {
							getAlbumApi(item.id).then((res: Partial<AlbumDetail>) => {
								if (res.code === 200) {
									state.hotAlbums[index].songs = res.songs.slice(0, 10);
									state.hotAlbums[index].realSongs = res.songs;
								}
							});
						});
					}
				})
				.then(() => (state.isRequesting = false));
		};
		let concatAlbumsThrottle = null;
		const strickConcatAlbumsThrottle = () => {
			if (!concatAlbumsThrottle) {
				concatAlbumsThrottle = throttle(concatAlbums, 300, true);
			}
			concatAlbumsThrottle();
		};
		const scrollInstance = scrollToBottom();
		const handleScroll = (e) => {
			if (currentActiveNavIndex.value !== 0) return;
			scrollInstance(e.target, () => {
				strickConcatAlbumsThrottle();
			});
		};
		const navigateToAlbumDetail = (albumId) => {
			router.push({ name: "albumDetail", query: { id: albumId, artistId: id.value } });
		};
		const getArtistDesc = () => {
			getArtistDescApi(id.value).then((res: any) => {
				if (res.code === 200) {
					state.artistDesc = res;
				}
			});
		};
		const getSimilarArtist = () => {
			getSimilarArtistApi(id.value).then((res: Partial<SimilarArtistsResponse>) => {
				if (res.code === 200) {
					state.similarArtists = res.artists;
				}
			});
		};
		return {
			...toRefs(state),
			isSubed,
			subArtist,
			collectMusic,
			handleDownloadMusic,
			YYYYMMDD,
			handleScroll,
			console,
			navigateToAlbumDetail,
			currentActiveNavIndex,
		};
	},
});
</script>

<style scoped lang="scss">
.topArea {
	.alias {
		margin: 10px 0;
	}
	.collect {
		height: 30px;
		width: 78px;
	}
	.hover-btn {
		&:hover {
			background-color: rgba($color: #000000, $alpha: 0.1) !important;
		}
	}
}
.boderLine {
	margin-top: -7px;
	position: relative;
	z-index: -1;
}
.top50Cover {
	width: 150px;
	height: 150px;
	line-height: 0.8;
	&::before {
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-image: linear-gradient(white, rgba(170, 118, 166, 0.8));
		z-index: 1;
	}
	&::after {
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba($color: #000000, $alpha: 0.28);
		background-image: radial-gradient(transparent, rgb(0, 0, 0, 0.5));
		z-index: 1;
	}
	> div {
		z-index: 2;
	}
	> div:first-child {
		font-size: 40px;
	}
	> div:last-child {
		font-size: 60px;
	}
}
.findAll {
	padding-right: 26px;
}
.albums {
	margin-top: 55px;

	.albumName {
		max-width: 80%;
	}
}
.textDes {
	letter-spacing: 1.5px;
}
</style>
